﻿using System;

namespace Popw.LiveBlog.Services
{
	public interface ITimeFormattingService
	{
		int UtcOffset { get; }
		bool UsesDaylightSaving { get; }
		string GetFormattedTime(DateTime utcDateTime);
	}

	public class TimeFormattingService : ITimeFormattingService
	{
		public TimeFormattingService()
		{
			UtcOffset = Config.Settings.UfcOffset;
			UsesDaylightSaving = Config.Settings.UsesDaylightSaving;
		}

		public int UtcOffset { get; private set; }
		public bool UsesDaylightSaving { get; private set; }

		public string GetFormattedTime(DateTime utcDateTime)
		{
			var now = GetAdjustedTime(DateTime.UtcNow);
			var input = GetAdjustedTime(utcDateTime);
			var difference = now.Subtract(input);
			if (difference > new TimeSpan(0, 59, 59))
			{
				if (now.Date == input.Date)
					return String.Format("Today, {0}", input.ToString("t"));
				if (now.Date.AddDays(-1) == input.Date)
					return String.Format("Yesterday, {0}", input.ToString("t"));
				return input.ToString("MMMM d, yyyy, h:mmt");
			}
			if (difference > new TimeSpan(0, 2, 00))
				return String.Format("{0} minutes ago", difference.Minutes);
			if (difference > new TimeSpan(0, 1, 00))
				return "1 minute ago";
			return "Less than a minute ago";
		}

		private DateTime GetAdjustedTime(DateTime dateTime)
		{
			double offset = UtcOffset;
			if (UsesDaylightSaving && IsDaylightSaving(dateTime)) offset++;
			return dateTime.AddHours(offset);
		}

		private bool IsDaylightSaving(DateTime localTime)
		{
			DateTime startDate;
			DateTime endDate;
			if ((UtcOffset < -4) && (UtcOffset > -11))
			{
				// us dst
				if (localTime.Year < 2007)
				{
					startDate = new DateTime(localTime.Year, 4, Convert.ToInt32((2 + 6 * localTime.Year - Math.Floor((double)localTime.Year / 4)) % 7) + 1, 2, 0, 0);
					endDate = new DateTime(localTime.Year, 10, Convert.ToInt32(31 - (Math.Floor((double)localTime.Year * 5 / 4) + 1) % 7), 2, 0, 0);
				}
				else
				{
					startDate = new DateTime(localTime.Year, 3, 14 - Convert.ToInt32(Math.Floor(1 + (double)localTime.Year * 5 / 4) % 7), 2, 0, 0);
					endDate = new DateTime(localTime.Year, 11, 7 - Convert.ToInt32(Math.Floor(1 + (double)localTime.Year * 5 / 4) % 7), 2, 0, 0);
				}
				if ((localTime > startDate) && (localTime < endDate)) return true;
			}
			if ((UtcOffset > -1) && (UtcOffset < 5))
			{
				// european dst
				startDate = new DateTime(localTime.Year, 3, Convert.ToInt32(31 - (Math.Floor((double)localTime.Year * 5 / 4) + 1) % 7), 1, 0, 0);
				endDate = new DateTime(localTime.Year, 10, Convert.ToInt32(31 - (Math.Floor((double)localTime.Year * 5 / 4) + 1) % 7), 1, 0, 0);
				if ((localTime > startDate) && (localTime < endDate)) return true;
			}
			return false;
		}
	}
}